<template>
  <div class="groups-list">
    <div class="groups-header">
      <q-input
        v-model="searchQuery"
        placeholder="搜索群组"
        outlined
        dense
        class="search-input"
        autocomplete="off"
      >
        <template v-slot:prepend>
          <q-icon name="search" />
        </template>
      </q-input>
      <q-btn
        flat
        round
        dense
        icon="add"
        @click="showCreateGroupDialog = true"
        class="create-group-btn"
      />
    </div>

    <div class="groups-content">
      <div
        v-for="group in filteredGroups"
        :key="group.group_id"
        class="group-item"
        :class="{ active: currentTargetId === group.group_id }"
        @click="selectGroup(group.group_id)"
      >
        <q-avatar class="group-avatar" size="48px">
          <div class="avatar-placeholder">
            {{ (group.group_name[0] || 'G').toUpperCase() }}
          </div>
        </q-avatar>
        <div class="group-info">
          <div class="group-header">
            <div class="group-name">{{ group.group_name }}</div>
            <span class="group-time">{{ getLastMessageTime(group.group_id) }}</span>
          </div>
          <div class="group-preview">
            {{ getLastMessagePreview(group.group_id) }}
          </div>
        </div>
        <!-- 未读消息角标 -->
        <q-badge
          v-if="getUnreadCount(group) > 0"
          :label="getUnreadCount(group) > 99 ? '99+' : String(getUnreadCount(group))"
          color="primary"
          class="unread-badge"
          rounded
        />
        <!-- 如果没有序列号但有新消息，显示红点 -->
        <div
          v-else-if="hasNewMessages(group)"
          class="unread-dot"
        />
        <q-btn
          flat
          round
          dense
          icon="more_horiz"
          @click.stop="$emit('show-details', group)"
        >
          <q-tooltip>群组详情</q-tooltip>
        </q-btn>
      </div>

      <div v-if="filteredGroups.length === 0" class="empty-state">
        <q-icon name="group_outline" size="48px" color="grey-5" />
        <div class="empty-text">暂无群组</div>
      </div>
    </div>

    <!-- 添加群成员对话框 -->
    <q-dialog v-model="showAddMemberDialog">
      <q-card class="add-member-dialog">
        <q-card-section class="add-member-header">
          <div class="add-member-title">添加群成员</div>
        </q-card-section>
        <q-card-section class="add-member-body">
          <q-input
            v-model="memberSearchQuery"
            placeholder="搜索好友"
            outlined
            dense
            class="add-member-search"
          >
            <template v-slot:prepend>
              <q-icon name="search" />
            </template>
          </q-input>
          <div v-if="filteredFriendsForGroup.length === 0" class="empty-state">
            <q-icon name="people_outline" size="48px" color="grey-5" />
            <div class="empty-text">
              {{ friendsForGroup.length === 0 
                ? '暂无好友' 
                : groupMembers.length > 0 
                  ? '所有好友已添加到群组' 
                  : '暂无好友可添加' }}
            </div>
          </div>
          <div
            v-for="friend in filteredFriendsForGroup"
            :key="friend.to_id"
            class="friend-select-item"
            @click="handleAddMemberToGroup(friend.to_id)"
          >
            <q-avatar class="friend-avatar" size="40px">
              <div class="avatar-placeholder">
                {{ (friend.remark?.[0] || friend.to_id[0] || 'F').toUpperCase() }}
              </div>
            </q-avatar>
            <div class="friend-info">
              <div class="friend-name">{{ friend.remark || friend.to_id }}</div>
              <div v-if="friend.remark" class="friend-id">{{ friend.to_id }}</div>
            </div>
            <q-btn
              flat
              round
              dense
              icon="add"
              color="primary"
              :loading="addingMember === friend.to_id"
            />
          </div>
        </q-card-section>
        <q-card-actions align="right" class="add-member-actions">
          <q-btn flat label="关闭" @click="showAddMemberDialog = false" class="add-member-btn" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <!-- 设置管理员对话框 -->
    <q-dialog v-model="showSetAdminDialog">
      <q-card style="min-width: 400px">
        <q-card-section>
          <div class="text-h6">设置管理员</div>
        </q-card-section>
        <q-card-section style="max-height: 400px; overflow-y: auto">
          <q-input
            v-model="adminSearchQuery"
            placeholder="搜索成员"
            outlined
            dense
            class="q-mb-md"
          >
            <template v-slot:prepend>
              <q-icon name="search" />
            </template>
          </q-input>
          <div v-if="filteredMembersForAdmin.length === 0" class="empty-state">
            <q-icon name="people_outline" size="48px" color="grey-5" />
            <div class="empty-text">暂无可设置管理员的成员</div>
          </div>
          <div
            v-for="member in filteredMembersForAdmin"
            :key="member.member_id"
            class="member-select-item"
          >
            <q-avatar class="member-avatar" size="40px">
              <div class="avatar-placeholder">
                {{ (member.alias?.[0] || member.member_id[0] || 'M').toUpperCase() }}
              </div>
            </q-avatar>
            <div class="member-info">
              <div class="member-name">
                {{ member.alias || member.member_id }}
                <q-chip
                  v-if="member.role === 1"
                  size="sm"
                  color="primary"
                  text-color="white"
                  dense
                  class="q-ml-xs"
                >
                  管理员
                </q-chip>
                <q-chip
                  v-else-if="member.role === 2"
                  size="sm"
                  color="orange"
                  text-color="white"
                  dense
                  class="q-ml-xs"
                >
                  群主
                </q-chip>
              </div>
              <div class="member-id">{{ member.member_id }}</div>
            </div>
            <div class="member-actions">
              <q-btn
                v-if="member.role !== 1 && member.role !== 2"
                flat
                round
                dense
                icon="admin_panel_settings"
                color="primary"
                :loading="settingAdmin === member.member_id"
                @click="handleSetAdmin(member.member_id, 1)"
                title="设置为管理员"
              />
              <q-btn
                v-else-if="member.role === 1"
                flat
                round
                dense
                icon="person_remove"
                color="negative"
                :loading="settingAdmin === member.member_id"
                @click="handleSetAdmin(member.member_id, 0)"
                title="取消管理员"
              />
            </div>
          </div>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn flat label="关闭" @click="showSetAdminDialog = false" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <!-- 转让群主对话框 -->
    <q-dialog v-model="showTransferOwnerDialog">
      <q-card style="min-width: 400px">
        <q-card-section>
          <div class="text-h6">转让群主</div>
        </q-card-section>
        <q-card-section style="max-height: 400px; overflow-y: auto">
          <q-input
            v-model="transferOwnerSearchQuery"
            placeholder="搜索成员"
            outlined
            dense
            class="q-mb-md"
            autocomplete="off"
          >
            <template v-slot:prepend>
              <q-icon name="search" />
            </template>
          </q-input>
          <div
            v-for="member in filteredTransferMembers"
            :key="member.member_id"
            class="member-item"
          >
            <q-avatar class="member-avatar" size="40px">
              <div class="avatar-placeholder">
                {{ (member.alias?.[0] || member.member_id[0] || 'M').toUpperCase() }}
              </div>
            </q-avatar>
            <div class="member-info">
              <div class="member-name">{{ member.alias || member.member_id }}</div>
              <div class="member-id">{{ member.member_id }}</div>
            </div>
            <div class="member-actions">
              <q-btn
                flat
                round
                dense
                icon="swap_horiz"
                color="primary"
                :loading="transferringOwner === member.member_id"
                @click="handleTransferOwner(member.member_id)"
                title="转让群主"
              />
            </div>
          </div>
          <div v-if="filteredTransferMembers.length === 0" class="empty-state">
            <q-icon name="person_off" size="48px" color="grey-5" />
            <div class="empty-text">没有可转让的成员</div>
          </div>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn flat label="关闭" @click="showTransferOwnerDialog = false" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <!-- 编辑群组对话框 -->
    <q-dialog v-model="showEditGroupDialog">
      <q-card class="dialog-card">
        <q-card-section class="dialog-header">
          <div class="dialog-title">编辑群组</div>
        </q-card-section>
        <q-card-section class="dialog-body">
          <q-input
            v-model="editGroupName"
            placeholder="请输入群组名称"
            outlined
            dense
            autocomplete="off"
            autocapitalize="off"
            autocorrect="off"
            spellcheck="false"
            class="dialog-input"
            :loading="updatingGroup"
          />
          <q-input
            v-model="editGroupIntroduction"
            placeholder="请输入群组简介（可选）"
            outlined
            dense
            type="textarea"
            rows="3"
            autocomplete="off"
            autocapitalize="off"
            autocorrect="off"
            spellcheck="false"
            class="dialog-input q-mt-md"
          />
        </q-card-section>
        <q-card-actions align="right" class="dialog-actions">
          <q-btn flat label="取消" @click="showEditGroupDialog = false" class="dialog-btn" />
          <q-btn
            flat
            label="保存"
            color="primary"
            @click="handleUpdateGroup"
            :loading="updatingGroup"
            class="dialog-btn dialog-btn-primary"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <!-- 群组详情对话框 -->
    <q-dialog v-model="showGroupDetailsDialog" @show="loadGroupDetailsMembers">
      <q-card class="group-details-dialog" style="min-width: 600px; max-width: 800px; max-height: 85vh">
        <q-card-section class="dialog-header">
          <div class="dialog-title">群组详情</div>
          <q-space />
          <q-btn icon="close" flat round dense v-close-popup />
        </q-card-section>
        
        <q-card-section class="dialog-body" style="max-height: calc(85vh - 200px); overflow-y: auto">
          <!-- 群组基本信息 -->
          <div class="group-info-section">
            <div class="group-detail-item">
              <div class="detail-label">群组名称</div>
              <div class="detail-value">{{ currentGroupDetails?.group_name || '未知' }}</div>
            </div>
            <div class="group-detail-item" v-if="currentGroupDetails?.introduction">
              <div class="detail-label">群组简介</div>
              <div class="detail-value">{{ currentGroupDetails.introduction }}</div>
            </div>
            <div class="group-detail-item">
              <div class="detail-label">群主</div>
              <div class="detail-value">
                <span v-if="isGroupOwner(currentGroupDetails)">您（{{ currentGroupDetails?.owner_id }}）</span>
                <span v-else>{{ currentGroupDetails?.owner_id || '未知' }}</span>
              </div>
            </div>
            <div class="group-detail-item">
              <div class="detail-label">成员数量</div>
              <div class="detail-value">{{ currentGroupDetails?.member_count || groupDetailsMembers.length || 0 }} 人</div>
            </div>
            <div class="group-detail-item">
              <div class="detail-label">群组类型</div>
              <div class="detail-value">{{ currentGroupDetails?.group_type === 1 ? '私有群' : '公开群' }}</div>
            </div>
            <div class="group-detail-item">
              <div class="detail-label">加入方式</div>
              <div class="detail-value">{{ currentGroupDetails?.apply_join_type === 1 ? '需要审批' : '自由加入' }}</div>
            </div>
          </div>

          <!-- 群成员列表 -->
          <div class="members-section">
            <div class="section-header">
              <div class="section-title">
                <q-icon name="people" size="20px" class="q-mr-xs" />
                群成员 ({{ groupDetailsMembers.length }})
              </div>
              <q-input
                v-model="groupDetailsMemberSearch"
                placeholder="搜索成员"
                outlined
                dense
                class="member-search-input"
                autocomplete="off"
                clearable
              >
                <template v-slot:prepend>
                  <q-icon name="search" />
                </template>
              </q-input>
            </div>
            
            <div class="members-list">
              <div v-if="loadingGroupDetailsMembers" class="loading-members">
                <q-spinner color="primary" size="32px" />
                <div class="loading-text">加载成员中...</div>
              </div>
              <div v-else-if="filteredGroupDetailsMembers.length === 0" class="empty-members">
                <q-icon name="people_outline" size="48px" color="grey-5" />
                <div class="empty-text">{{ groupDetailsMemberSearch ? '未找到匹配的成员' : '暂无成员' }}</div>
              </div>
              <div
                v-else
                v-for="member in filteredGroupDetailsMembers"
                :key="member.member_id"
                class="member-item-detail"
              >
                <q-avatar class="member-avatar-detail" size="40px">
                  <div class="avatar-placeholder">
                    {{ (member.alias?.[0] || member.member_id[0] || 'M').toUpperCase() }}
                  </div>
                </q-avatar>
                <div class="member-info-detail">
                  <div class="member-name-detail">
                    {{ member.alias || member.member_id }}
                    <q-chip
                      v-if="member.role === 2"
                      size="sm"
                      color="orange"
                      text-color="white"
                      dense
                      class="q-ml-xs"
                    >
                      群主
                    </q-chip>
                    <q-chip
                      v-else-if="member.role === 1"
                      size="sm"
                      color="primary"
                      text-color="white"
                      dense
                      class="q-ml-xs"
                    >
                      管理员
                    </q-chip>
                  </div>
                  <div class="member-id-detail">{{ member.member_id }}</div>
                </div>
              </div>
            </div>
          </div>
        </q-card-section>

        <!-- 底部操作按钮 -->
        <q-separator />
        <q-card-actions class="dialog-actions-bottom">
          <q-space />
          <q-btn
            flat
            label="清空聊天记录"
            color="negative"
            @click="handleClearGroupMessages"
            :loading="clearingGroupMessages"
            class="action-btn-danger"
          />
          <q-btn
            v-if="!isGroupOwner(currentGroupDetails)"
            flat
            label="退出群组"
            color="negative"
            @click="handleLeaveGroupFromDetails"
            :loading="leavingGroup"
            class="action-btn-danger"
          />
          <q-btn
            flat
            label="关闭"
            @click="showGroupDetailsDialog = false"
            class="dialog-btn"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <!-- 移除成员对话框 -->
    <q-dialog v-model="showRemoveMemberDialog">
      <q-card style="min-width: 400px">
        <q-card-section>
          <div class="text-h6">移除成员</div>
        </q-card-section>
        <q-card-section style="max-height: 400px; overflow-y: auto">
          <q-input
            v-model="removeMemberSearchQuery"
            placeholder="搜索成员"
            outlined
            dense
            class="q-mb-md"
          >
            <template v-slot:prepend>
              <q-icon name="search" />
            </template>
          </q-input>
          <div v-if="filteredMembersForRemove.length === 0" class="empty-state">
            <q-icon name="people_outline" size="48px" color="grey-5" />
            <div class="empty-text">暂无可移除的成员</div>
          </div>
          <div
            v-for="member in filteredMembersForRemove"
            :key="member.member_id"
            class="member-select-item"
          >
            <q-avatar class="member-avatar" size="40px">
              <div class="avatar-placeholder">
                {{ (member.alias?.[0] || member.member_id[0] || 'M').toUpperCase() }}
              </div>
            </q-avatar>
            <div class="member-info">
              <div class="member-name">
                {{ member.alias || member.member_id }}
                <q-chip
                  v-if="member.role === 1"
                  size="sm"
                  color="primary"
                  text-color="white"
                  dense
                  class="q-ml-xs"
                >
                  管理员
                </q-chip>
                <q-chip
                  v-else-if="member.role === 2"
                  size="sm"
                  color="orange"
                  text-color="white"
                  dense
                  class="q-ml-xs"
                >
                  群主
                </q-chip>
              </div>
              <div class="member-id">{{ member.member_id }}</div>
            </div>
            <div class="member-actions">
              <q-btn
                v-if="member.role !== 2"
                flat
                round
                dense
                icon="person_remove"
                color="negative"
                :loading="removingMember === member.member_id"
                @click="handleRemoveMember(member.member_id)"
                title="移除成员"
              />
            </div>
          </div>
        </q-card-section>
        <q-card-actions align="right">
          <q-btn flat label="关闭" @click="showRemoveMemberDialog = false" />
        </q-card-actions>
      </q-card>
    </q-dialog>

    <!-- 创建群组对话框 -->
    <q-dialog v-model="showCreateGroupDialog">
      <q-card class="dialog-card">
        <q-card-section class="dialog-header">
          <div class="dialog-title">创建群组</div>
        </q-card-section>
        <q-card-section class="dialog-body">
          <q-input
            v-model="newGroupName"
            placeholder="请输入群组名称"
            outlined
            dense
            autocomplete="off"
            autocapitalize="off"
            autocorrect="off"
            spellcheck="false"
            class="dialog-input"
            :loading="creatingGroup"
          />
          <q-input
            v-model="newGroupIntroduction"
            placeholder="请输入群组简介（可选）"
            outlined
            dense
            type="textarea"
            rows="3"
            autocomplete="off"
            autocapitalize="off"
            autocorrect="off"
            spellcheck="false"
            class="dialog-input q-mt-md"
          />
        </q-card-section>
        <q-card-actions align="right" class="dialog-actions">
          <q-btn flat label="取消" @click="showCreateGroupDialog = false" class="dialog-btn" />
          <q-btn
            flat
            label="创建"
            color="primary"
            @click="handleCreateGroup"
            :loading="creatingGroup"
            class="dialog-btn dialog-btn-primary"
          />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, onUnmounted } from 'vue';
import { createGroup, addGroupMember, getGroupMembers, getUserGroups, updateGroup, getGroup, removeGroupMember } from '../services/im-group';
import { getFriends } from '../services/im-friendship';
import { useQuasar } from 'quasar';
import { getUserAsync, getUser } from '../services/auth';
import { getUserChats, ImChat } from '../services/im-chat';
import { useChatStore } from '../stores/chat';
import { calculateUnreadCount, hasNewMessages as hasNewMessagesUtil } from '../utils/unread-messages';

// 简单的UUID生成函数
const generateUUID = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
};

const $q = useQuasar();
const chatStore = useChatStore();

const groups = ref<any[]>([]);
const chats = ref<ImChat[]>([]);
const searchQuery = ref('');
const showCreateGroupDialog = ref(false);
const newGroupName = ref('');
const newGroupIntroduction = ref('');
const creatingGroup = ref(false);
const showAddMemberDialog = ref(false);
const showSetAdminDialog = ref(false);
const showTransferOwnerDialog = ref(false);
const showEditGroupDialog = ref(false);
const showGroupDetailsDialog = ref(false);
const showRemoveMemberDialog = ref(false);
const currentGroupId = ref<string | null>(null);
const friendsForGroup = ref<any[]>([]);
const groupMembers = ref<any[]>([]);
const groupMembersForAdmin = ref<any[]>([]);
const groupMembersForTransfer = ref<any[]>([]);
const groupMembersForRemove = ref<any[]>([]);
const memberSearchQuery = ref('');
const adminSearchQuery = ref('');
const transferOwnerSearchQuery = ref('');
const removeMemberSearchQuery = ref('');
const addingMember = ref<string | null>(null);
const settingAdmin = ref<string | null>(null);
const transferringOwner = ref<string | null>(null);
const removingMember = ref<string | null>(null);
const updatingGroup = ref(false);
const editGroupName = ref('');
const editGroupIntroduction = ref('');
const currentGroupDetails = ref<any>(null);
const groupDetailsMembers = ref<any[]>([]);
const groupDetailsMemberSearch = ref('');
const clearingGroupMessages = ref(false);
const leavingGroup = ref(false);
const loadingGroupDetailsMembers = ref(false);

const filteredGroups = computed(() => {
  if (!searchQuery.value) return groups.value;
  const query = searchQuery.value.toLowerCase();
  return groups.value.filter((g) =>
    g.group_name.toLowerCase().includes(query)
  );
});

const loadGroups = async (forceRefresh: boolean = false) => {
  try {
    // forceRefresh 为 true 时，强制从服务器获取最新数据（不使用缓存）
    const data = await getUserGroups(!forceRefresh);
    groups.value = data.groups || [];
    console.log('群组列表已加载:', groups.value.length, '个群组', forceRefresh ? '(强制刷新)' : '(使用缓存)');
    
    // 加载聊天列表以获取未读消息数
    await loadChats();
  } catch (error: any) {
    console.error('获取群组列表失败:', error);
  }
};

const loadChats = async () => {
  try {
    const loadedChats = await getUserChats();
    chats.value = loadedChats;
  } catch (error: any) {
    console.error('加载聊天列表失败:', error);
  }
};

// 计算未读消息数（使用统一工具函数）
const getUnreadCount = (group: any): number => {
  // 查找与该群组相关的聊天记录（群聊，chat_type = 2）
  const chat = chats.value.find(c => 
    c.chat_type === 2 && c.to_id === group.group_id
  );
  
  return calculateUnreadCount(
    chatStore.messages,
    group.group_id,
    2, // chat_type = 2 表示群聊
    chat?.read_sequence
  );
};

// 检查是否有新消息（使用统一工具函数）
const hasNewMessages = (group: any): boolean => {
  // 查找与该群组相关的聊天记录
  const chat = chats.value.find(c => 
    c.chat_type === 2 && c.to_id === group.group_id
  );
  
  if (!chat) {
    return false;
  }
  
  return hasNewMessagesUtil(
    chatStore.messages,
    group.group_id,
    2, // chat_type = 2 表示群聊
    chat.read_sequence
  );
};

// 格式化时间
const formatTime = (timestamp: number): string => {
  if (!timestamp) return '';
  
  // 确保时间戳是数字类型，如果是字符串则转换
  let ts = timestamp;
  if (typeof ts === 'string') {
    ts = parseInt(ts, 10);
  }
  
  // 如果时间戳小于 13 位（秒级），转换为毫秒级
  if (ts < 1000000000000) {
    ts = ts * 1000;
  }
  
  const date = new Date(ts);
  
  // 检查日期是否有效
  if (isNaN(date.getTime())) {
    console.warn('无效的时间戳:', timestamp);
    return '';
  }
  
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const messageDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  const diffTime = now.getTime() - date.getTime();
  const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));

  if (diffDays === 0) {
    // 今天：显示时间 HH:mm
    const hours = date.getHours().toString().padStart(2, '0');
    const minutes = date.getMinutes().toString().padStart(2, '0');
    return `${hours}:${minutes}`;
  } else if (diffDays === 1) {
    // 昨天
    return '昨天';
  } else if (diffDays < 7) {
    // 一周内：显示星期几
    const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    return weekdays[date.getDay()];
  } else {
    // 更早：显示日期 MM/DD
    const month = (date.getMonth() + 1).toString().padStart(2, '0');
    const day = date.getDate().toString().padStart(2, '0');
    return `${month}/${day}`;
  }
};

// 获取最后一条消息预览
const getLastMessagePreview = (groupId: string): string => {
  const allMessages = chatStore.messages;
  const normalizedGroupId = String(groupId).trim();
  
  // 标准化群组ID的辅助函数
  const normalizeGroupId = (id: string) => id.replace(/^group_/i, '').trim().toLowerCase();
  
  const lastMessage = allMessages
    .filter(msg => {
      // 只匹配群聊消息（chat_type = 2）
      if (msg.chat_type !== 2) {
        return false;
      }
      
      // 检查 to_user_id 是否匹配群组ID
      const msgToId = String(msg.to_user_id || '').trim();
      const normalizedMsgToId = normalizeGroupId(msgToId);
      const normalizedTargetId = normalizeGroupId(normalizedGroupId);
      return msgToId === normalizedGroupId || normalizedMsgToId === normalizedTargetId;
    })
    .sort((a, b) => {
      // 使用 timestamp_ms 如果存在，否则使用 timestamp
      const aTime = a.timestamp_ms || a.timestamp;
      const bTime = b.timestamp_ms || b.timestamp;
      return bTime - aTime;
    })[0];
  
  if (!lastMessage) {
    // 检查是否有未读消息（说明后端有消息，只是还没加载）
    const chat = chats.value.find(c => 
      c.chat_type === 2 && c.to_id === groupId
    );
    
    if (chat && chat.sequence && chat.read_sequence !== undefined) {
      const sequence = chat.sequence;
      const readSequence = chat.read_sequence;
      if (sequence > readSequence) {
        // 有未读消息，返回空字符串
        return '';
      }
    }
    
    return '暂无消息';
  }
  
  if (lastMessage.file_name) {
    return `[文件] ${lastMessage.file_name}`;
  }
  
  const text = lastMessage.message.replace(/[#*_`\[\]()]/g, '').trim();
  return text.length > 20 ? text.substring(0, 20) + '...' : text;
};

// 获取最后一条消息时间
const getLastMessageTime = (groupId: string): string => {
  const allMessages = chatStore.messages;
  const normalizedGroupId = String(groupId).trim();
  
  // 标准化群组ID的辅助函数
  const normalizeGroupId = (id: string) => id.replace(/^group_/i, '').trim().toLowerCase();
  
  const lastMessage = allMessages
    .filter(msg => {
      // 只匹配群聊消息（chat_type = 2）
      if (msg.chat_type !== 2) {
        return false;
      }
      
      // 检查 to_user_id 是否匹配群组ID
      const msgToId = String(msg.to_user_id || '').trim();
      const normalizedMsgToId = normalizeGroupId(msgToId);
      const normalizedTargetId = normalizeGroupId(normalizedGroupId);
      return msgToId === normalizedGroupId || normalizedMsgToId === normalizedTargetId;
    })
    .sort((a, b) => {
      // 使用 timestamp_ms 如果存在，否则使用 timestamp
      const aTime = a.timestamp_ms || a.timestamp;
      const bTime = b.timestamp_ms || b.timestamp;
      return bTime - aTime;
    })[0];
  
  if (!lastMessage) return '';
  
  // 使用 timestamp_ms 如果存在，否则使用 timestamp
  const timestamp = lastMessage.timestamp_ms || lastMessage.timestamp;
  return formatTime(timestamp);
};

const loadFriendsForGroup = async () => {
  try {
    friendsForGroup.value = await getFriends();
    console.log('加载好友列表用于添加群成员:', friendsForGroup.value.length, '个好友');
    
    // 如果当前有选中的群组，加载该群组的成员列表
    if (currentGroupId.value) {
      try {
        groupMembers.value = await getGroupMembers(currentGroupId.value);
        console.log('加载群成员列表:', groupMembers.value.length, '个成员', '群组ID:', currentGroupId.value);
        console.log('群成员ID列表:', groupMembers.value.map(m => m.member_id));
      } catch (error: any) {
        console.error('获取群成员列表失败:', error);
        groupMembers.value = [];
      }
    } else {
      console.warn('currentGroupId 未设置，无法加载群成员列表');
      groupMembers.value = [];
    }
  } catch (error: any) {
    console.error('获取好友列表失败:', error);
    friendsForGroup.value = [];
  }
};

const loadGroupMembersForAdmin = async () => {
  if (!currentGroupId.value) return;
  try {
    const members = await getGroupMembers(currentGroupId.value);
    // 过滤掉群主（role=2），显示所有成员（包括管理员和普通成员），以便可以设置/取消管理员
    groupMembersForAdmin.value = members.filter(m => m.role !== 2);
  } catch (error: any) {
    console.error('获取群成员列表失败:', error);
    groupMembersForAdmin.value = [];
  }
};

const filteredFriendsForGroup = computed(() => {
  // 先过滤掉已经在群组中的成员
  // 创建一个包含所有可能的成员ID格式的集合（member_id、open_id、snowflake_id、用户名等）
  const memberIds = new Set<string>();
  groupMembers.value.forEach(m => {
    if (m.member_id) {
      memberIds.add(m.member_id);
    }
  });
  
  console.log('过滤好友列表 - 群成员ID集合:', Array.from(memberIds));
  console.log('过滤好友列表 - 好友总数:', friendsForGroup.value.length);
  
  // 过滤好友列表，排除已经在群组中的成员
  // 需要匹配好友的 to_id 以及可能的其他ID格式（open_id、snowflake_id等）
  let filtered = friendsForGroup.value.filter(f => {
    // 检查 to_id 是否在成员列表中
    if (memberIds.has(f.to_id)) {
      console.log('好友已在群组中 (to_id匹配):', f.to_id);
      return false; // 已在群组中，排除
    }
    
    // 如果好友有 user 信息，也检查 open_id、snowflake_id 和 name
    if (f.user) {
      if (f.user.open_id && memberIds.has(f.user.open_id)) {
        console.log('好友已在群组中 (open_id匹配):', f.to_id, 'open_id:', f.user.open_id);
        return false; // open_id 匹配，已在群组中
      }
      if (f.user.snowflake_id && memberIds.has(String(f.user.snowflake_id))) {
        console.log('好友已在群组中 (snowflake_id匹配):', f.to_id, 'snowflake_id:', f.user.snowflake_id);
        return false; // snowflake_id 匹配，已在群组中
      }
      if (f.user.name && memberIds.has(f.user.name)) {
        console.log('好友已在群组中 (name匹配):', f.to_id, 'name:', f.user.name);
        return false; // 用户名匹配，已在群组中
      }
    }
    
    // 不在群组中，保留
    return true;
  });
  
  console.log('过滤后的好友数量:', filtered.length);
  
  // 再根据搜索关键词过滤
  if (memberSearchQuery.value) {
    const query = memberSearchQuery.value.toLowerCase();
    filtered = filtered.filter(
      (f) =>
        f.to_id.toLowerCase().includes(query) ||
        (f.remark && f.remark.toLowerCase().includes(query)) ||
        (f.user?.name && f.user.name.toLowerCase().includes(query))
    );
  }
  
  return filtered;
});

const filteredMembersForAdmin = computed(() => {
  let filtered = groupMembersForAdmin.value;
  
  // 根据搜索关键词过滤
  if (adminSearchQuery.value) {
    const query = adminSearchQuery.value.toLowerCase();
    filtered = filtered.filter(
      (m) =>
        m.member_id.toLowerCase().includes(query) ||
        (m.alias && m.alias.toLowerCase().includes(query))
    );
  }
  
  return filtered;
});

const filteredTransferMembers = computed(() => {
  let filtered = groupMembersForTransfer.value;
  
  // 根据搜索关键词过滤
  if (transferOwnerSearchQuery.value) {
    const query = transferOwnerSearchQuery.value.toLowerCase();
    filtered = filtered.filter(
      (m) =>
        m.member_id.toLowerCase().includes(query) ||
        (m.alias && m.alias.toLowerCase().includes(query))
    );
  }
  
  return filtered;
});

const filteredMembersForRemove = computed(() => {
  let filtered = groupMembersForRemove.value;
  
  // 根据搜索关键词过滤
  if (removeMemberSearchQuery.value) {
    const query = removeMemberSearchQuery.value.toLowerCase();
    filtered = filtered.filter(
      (m) =>
        m.member_id.toLowerCase().includes(query) ||
        (m.alias && m.alias.toLowerCase().includes(query))
    );
  }
  
  return filtered;
});

const filteredGroupDetailsMembers = computed(() => {
  let filtered = groupDetailsMembers.value;
  
  // 根据搜索关键词过滤
  if (groupDetailsMemberSearch.value) {
    const query = groupDetailsMemberSearch.value.toLowerCase();
    filtered = filtered.filter(
      (m) =>
        m.member_id.toLowerCase().includes(query) ||
        (m.alias && m.alias.toLowerCase().includes(query))
    );
  }
  
  return filtered;
});

const selectGroup = (groupId: string) => {
  // 从群组列表中查找群组信息，传递群组名称
  const group = groups.value.find(g => g.group_id === groupId);
  if (group && group.group_name) {
    emit('select-group', groupId, group.group_name);
  } else {
    emit('select-group', groupId);
  }
};

const handleCreateGroup = async () => {
  if (!newGroupName.value.trim()) {
    $q.notify({
      type: 'warning',
      message: '请输入群组名称',
    });
    return;
  }

  creatingGroup.value = true;
  try {
    const groupId = generateUUID();
    await createGroup({
      group_id: groupId,
      group_name: newGroupName.value.trim(),
      group_type: 1, // 私有群
      apply_join_type: 1, // 需要审批
      introduction: newGroupIntroduction.value.trim() || undefined,
    });
    $q.notify({
      type: 'positive',
      message: '群组创建成功',
    });
    showCreateGroupDialog.value = false;
    newGroupName.value = '';
    newGroupIntroduction.value = '';
    await loadGroups();
  } catch (error: any) {
    $q.notify({
      type: 'negative',
      message: error.message || '创建群组失败',
    });
  } finally {
    creatingGroup.value = false;
  }
};

const handleAddMemberToGroup = async (friendId: string) => {
  if (!currentGroupId.value) return;
  
  addingMember.value = friendId;
  try {
    const finalGroupId = await addGroupMember(currentGroupId.value, {
      member_id: friendId,
      role: 0, // 普通成员
      alias: undefined,
    });
    
    // 如果group_id改变了（从2人升级到3人），更新currentGroupId
    if (finalGroupId && finalGroupId !== currentGroupId.value) {
      console.log('群组ID已更新，从', currentGroupId.value, '更新为', finalGroupId);
      currentGroupId.value = finalGroupId;
    }
    
    $q.notify({
      type: 'positive',
      message: '已成功添加好友到群组',
    });
    // 重新加载群组成员列表，以便在对话框中过滤掉已添加的成员
    const groupIdToUse = finalGroupId || currentGroupId.value;
    if (groupIdToUse) {
      groupMembers.value = await getGroupMembers(groupIdToUse);
    }
    // 强制刷新群组列表以更新成员数量（不使用缓存，确保从服务器获取最新数据）
    await loadGroups(true);
  } catch (error: any) {
    $q.notify({
      type: 'negative',
      message: error.message || '添加群成员失败',
    });
  } finally {
    addingMember.value = null;
  }
};

const handleSetAdmin = async (memberId: string, role: number) => {
  if (!currentGroupId.value) return;
  
  settingAdmin.value = memberId;
  try {
    const { updateMemberRole } = await import('../services/im-group');
    await updateMemberRole(currentGroupId.value, memberId, role);
    
    const roleName = role === 1 ? '管理员' : '普通成员';
    $q.notify({
      type: 'positive',
      message: `已成功${role === 1 ? '设置' : '取消'}${roleName}`,
    });
    // 重新加载群组成员列表
    await loadGroupMembersForAdmin();
  } catch (error: any) {
    $q.notify({
      type: 'negative',
      message: error.message || '更新成员角色失败',
    });
  } finally {
    settingAdmin.value = null;
  }
};

const handleTransferOwner = async (memberId: string) => {
  if (!currentGroupId.value) return;
  
  $q.dialog({
    title: '确认转让群主',
    message: `确定要将群主转让给该成员吗？转让后您将失去群主权限。`,
    cancel: true,
    persistent: true,
  }).onOk(async () => {
    transferringOwner.value = memberId;
    try {
      const { transferGroupOwner } = await import('../services/im-group');
      await transferGroupOwner(currentGroupId.value, memberId);
      
      $q.notify({
        type: 'positive',
        message: '群主已成功转让',
      });
      
      // 关闭对话框
      showTransferOwnerDialog.value = false;
      
      // 如果当前正在查看这个群组，刷新群组信息
      if (props.currentTargetId === currentGroupId.value) {
        emit('select-group', currentGroupId.value);
      }
      
      // 强制刷新群组列表（不使用缓存，确保从服务端获取最新数据）
      await loadGroups(true);
    } catch (error: any) {
      $q.notify({
        type: 'negative',
        message: error.message || '转让群主失败',
      });
    } finally {
      transferringOwner.value = null;
    }
  });
};

const currentUser = ref<any>(null);

// 加载当前用户信息
const loadCurrentUser = async () => {
  try {
    currentUser.value = await getUserAsync();
    console.log('当前用户信息已加载:', currentUser.value);
  } catch (error) {
    console.error('获取当前用户失败:', error);
    currentUser.value = null;
  }
};

const isGroupOwner = (group: any): boolean => {
  // 如果 currentUser 还没加载，尝试从同步存储获取（作为后备）
  let user = currentUser.value;
  if (!user) {
    try {
      user = getUser();
      if (user) {
        currentUser.value = user; // 更新响应式引用
      }
    } catch (error) {
      console.warn('无法获取用户信息:', error);
    }
  }
  
  if (!user || !group.owner_id) {
    console.log('[群主判断] 用户或群主ID为空:', { 
      hasUser: !!user, 
      ownerId: group.owner_id,
      groupName: group.group_name 
    });
    return false;
  }
  
  const ownerId = String(group.owner_id).trim();
  const userOpenId = user.open_id ? String(user.open_id).trim() : '';
  const userSnowflakeId = user.snowflake_id ? String(user.snowflake_id).trim() : '';
  const userId = String(user.id).trim();
  const userName = user.name ? String(user.name).trim() : '';
  const userPhone = user.phone ? String(user.phone).trim() : '';
  
  // 检查多种可能的ID匹配方式
  // get_external_id() 优先返回用户名，其次手机号，最后是 open_id
  const isOwner = ownerId === userName ||
                  ownerId === userPhone ||
                  ownerId === userOpenId || 
                  ownerId === userSnowflakeId ||
                  ownerId === userId;
  
  // 添加调试日志
  if (!isOwner) {
    console.log('[群主判断] 不是群主:', {
      groupName: group.group_name,
      ownerId: ownerId,
      userName: userName || '(无)',
      userPhone: userPhone || '(无)',
      userOpenId: userOpenId || '(无)',
      userSnowflakeId: userSnowflakeId || '(无)',
      userId: userId,
      matches: {
        name: ownerId === userName,
        phone: ownerId === userPhone,
        openId: ownerId === userOpenId,
        snowflakeId: ownerId === userSnowflakeId,
        id: ownerId === userId
      }
    });
  } else {
    const matchedField = ownerId === userName ? 'name' :
                         ownerId === userPhone ? 'phone' :
                         ownerId === userOpenId ? 'open_id' : 
                         ownerId === userSnowflakeId ? 'snowflake_id' : 'id';
    console.log('[群主判断] 是群主:', {
      groupName: group.group_name,
      ownerId: ownerId,
      matchedField: matchedField
    });
  }
  
  return isOwner;
};

const isGroupOwnerSync = async (group: any): Promise<boolean> => {
  try {
    const user = await getUserAsync();
    if (!user) {
      console.log('[群主判断-异步] 用户信息为空');
      return false;
    }
    
    const ownerId = String(group.owner_id).trim();
    const userOpenId = user.open_id ? String(user.open_id).trim() : '';
    const userSnowflakeId = user.snowflake_id ? String(user.snowflake_id).trim() : '';
    const userId = String(user.id).trim();
    const userName = user.name ? String(user.name).trim() : '';
    const userPhone = user.phone ? String(user.phone).trim() : '';
    
    const isOwner = ownerId === userName ||
                    ownerId === userPhone ||
                    ownerId === userOpenId || 
                    ownerId === userSnowflakeId ||
                    ownerId === userId;
    
    // 添加调试日志
    if (!isOwner) {
      console.log('[群主判断-异步] 不是群主:', {
        groupName: group.group_name,
        ownerId: ownerId,
        userName: userName || '(无)',
        userPhone: userPhone || '(无)',
        userOpenId: userOpenId || '(无)',
        userSnowflakeId: userSnowflakeId || '(无)',
        userId: userId
      });
    }
    
    return isOwner;
  } catch (error) {
    console.error('[群主判断-异步] 错误:', error);
    return false;
  }
};

// 注意：isGroupAdmin 是异步函数，不能在模板中直接使用
// 移除成员功能目前只允许群主使用，管理员功能可以在handleMenuAction中检查

const loadGroupMembersForRemove = async () => {
  if (!currentGroupId.value) return;
  try {
    const members = await getGroupMembers(currentGroupId.value, false);
    // 过滤掉群主（role=2），只显示可以移除的成员
    groupMembersForRemove.value = members.filter(m => m.role !== 2);
  } catch (error: any) {
    console.error('获取群成员列表失败:', error);
    groupMembersForRemove.value = [];
  }
};

const loadGroupMembersForTransfer = async () => {
  if (!currentGroupId.value) return;
  try {
    const members = await getGroupMembers(currentGroupId.value, false);
    // 过滤掉群主（role=2），只显示可以转让的成员
    groupMembersForTransfer.value = members.filter(m => m.role !== 2);
  } catch (error: any) {
    console.error('获取群成员列表失败:', error);
    groupMembersForTransfer.value = [];
  }
};

// 加载群组详情中的成员列表
const loadGroupDetailsMembers = async () => {
  if (!currentGroupDetails.value?.group_id) return;
  
  loadingGroupDetailsMembers.value = true;
  try {
    // 确保用户信息已加载，以便正确判断是否是群主
    if (!currentUser.value) {
      await loadCurrentUser();
    }
    
    const members = await getGroupMembers(currentGroupDetails.value.group_id, false);
    groupDetailsMembers.value = members;
    groupDetailsMemberSearch.value = '';
    console.log('群组详情成员列表已加载:', members.length, '个成员');
  } catch (error: any) {
    console.error('获取群组成员列表失败:', error);
    groupDetailsMembers.value = [];
    $q.notify({
      type: 'warning',
      message: '加载群成员列表失败',
      position: 'top',
    });
  } finally {
    loadingGroupDetailsMembers.value = false;
  }
};

// 从群组详情对话框清空聊天记录
const handleClearGroupMessages = async () => {
  if (!currentGroupDetails.value) return;
  
  $q.dialog({
    title: '确认清空',
    message: `确定要清空群组 "${currentGroupDetails.value.group_name}" 的本地消息吗？此操作只删除本地存储的消息，不会影响服务器上的消息。`,
    cancel: true,
    persistent: true,
  }).onOk(async () => {
    clearingGroupMessages.value = true;
    try {
      const { clearGroupChatMessages } = await import('../services/secure-storage');
      const { useChatStore } = await import('../stores/chat');
      const chatStore = useChatStore();
      
      // 调用 Tauri 命令清空群组本地消息
      const deletedCount = await clearGroupChatMessages(currentGroupDetails.value.group_id);
      
      console.log('Tauri 清空群组消息完成，删除数量:', deletedCount);
      
      // 同时更新内存中的消息列表
      try {
        const memoryDeletedCount = await chatStore.clearUserMessages(currentGroupDetails.value.group_id, []);
        console.log('内存中清空群组消息完成，删除数量:', memoryDeletedCount);
      } catch (error) {
        console.warn('清空内存中的群组消息失败:', error);
      }
      
      // 如果当前正在查看这个群组，需要重新加载消息
      if (props.currentTargetId === currentGroupDetails.value.group_id) {
        chatStore.setTarget('', 'Group');
        setTimeout(() => {
          chatStore.setTarget(currentGroupDetails.value.group_id, 'Group');
        }, 100);
      }
      
      $q.notify({
        type: 'positive',
        message: `已清空群组本地消息，共删除 ${deletedCount} 条消息`,
        timeout: 3000,
      });
    } catch (error: any) {
      console.error('清空群组本地消息失败:', error);
      $q.notify({
        type: 'negative',
        message: error.message || '清空群组本地消息失败',
      });
    } finally {
      clearingGroupMessages.value = false;
    }
  });
};

// 从群组详情对话框退出群组
const handleLeaveGroupFromDetails = async () => {
  if (!currentGroupDetails.value) return;
  
  $q.dialog({
    title: '确认退出',
    message: `确定要退出群组 "${currentGroupDetails.value.group_name}" 吗？`,
    cancel: true,
    persistent: true,
  }).onOk(async () => {
    leavingGroup.value = true;
    try {
      const { removeGroupMember } = await import('../services/im-group');
      const { getUserAsync } = await import('../services/auth');
      const { useChatStore } = await import('../stores/chat');
      const chatStore = useChatStore();
      
      const currentUser = await getUserAsync();
      if (!currentUser) {
        throw new Error('未登录，请先登录');
      }
      const currentUserId = currentUser.open_id || (currentUser.snowflake_id ? String(currentUser.snowflake_id) : undefined) || String(currentUser.id);
      
      // 先清理与该群组相关的聊天记录
      try {
        await chatStore.clearUserMessages(currentGroupDetails.value.group_id, []);
        console.log('已清理群组聊天记录:', currentGroupDetails.value.group_id);
      } catch (error) {
        console.warn('清理群组聊天记录失败:', error);
      }
      
      // 调用API退出群组
      await removeGroupMember(currentGroupDetails.value.group_id, currentUserId);
      
      // 关闭对话框
      showGroupDetailsDialog.value = false;
      
      // 如果当前正在查看这个群组，先清空当前目标
      if (props.currentTargetId === currentGroupDetails.value.group_id) {
        emit('select-group', '');
        chatStore.setTarget('', 'Group');
      }
      
      // 强制刷新群组列表
      await loadGroups(true);
      
      $q.notify({
        type: 'positive',
        message: '已退出群组',
      });
    } catch (error: any) {
      $q.notify({
        type: 'negative',
        message: error.message || '退出群组失败',
      });
    } finally {
      leavingGroup.value = false;
    }
  });
};

const handleMenuAction = async (action: string, group: any) => {
  switch (action) {
    case 'view_details':
      currentGroupId.value = group.group_id;
      try {
        const groupInfo = await getGroup(group.group_id);
        currentGroupDetails.value = groupInfo;
        showGroupDetailsDialog.value = true;
      } catch (error: any) {
        // 如果获取失败，使用当前群组信息作为后备
        console.warn('获取群组详情失败，使用当前群组信息:', error);
        currentGroupDetails.value = {
          ...group,
          member_count: group.member_count || 0,
        };
        showGroupDetailsDialog.value = true;
        // 不显示错误提示，因为我们已经使用了后备数据
      }
      break;
    case 'edit_group':
      // 检查是否是群主
      const isOwnerForEdit = await isGroupOwnerSync(group);
      if (!isOwnerForEdit) {
        $q.notify({
          type: 'warning',
          message: '只有群主才能编辑群组',
        });
        return;
      }
      currentGroupId.value = group.group_id;
      editGroupName.value = group.group_name || '';
      editGroupIntroduction.value = group.introduction || '';
      showEditGroupDialog.value = true;
      break;
    case 'remove_member':
      // 检查是否是群主（目前只允许群主移除成员，管理员功能可以后续添加）
      const isOwnerForRemove = await isGroupOwnerSync(group);
      if (!isOwnerForRemove) {
        // 尝试检查是否是管理员
        try {
          const user = await getUserAsync();
          if (user) {
            const currentUserId = user.open_id || (user.snowflake_id ? String(user.snowflake_id) : '') || String(user.id);
            const members = await getGroupMembers(group.group_id, false);
            const member = members.find(m => m.member_id === currentUserId);
            if (member?.role !== 1) {
              // 不是管理员
              $q.notify({
                type: 'warning',
                message: '只有群主或管理员才能移除成员',
              });
              return;
            }
          } else {
            $q.notify({
              type: 'warning',
              message: '只有群主或管理员才能移除成员',
            });
            return;
          }
        } catch {
          $q.notify({
            type: 'warning',
            message: '只有群主或管理员才能移除成员',
          });
          return;
        }
      }
      currentGroupId.value = group.group_id;
      showRemoveMemberDialog.value = true;
      loadGroupMembersForRemove();
      break;
    case 'add_member':
      currentGroupId.value = group.group_id;
      showAddMemberDialog.value = true;
      // 打开对话框时加载好友列表和群成员列表
      loadFriendsForGroup();
      break;
    case 'set_admin':
      // 检查是否是群主
      const isOwner = await isGroupOwnerSync(group);
      if (!isOwner) {
        $q.notify({
          type: 'warning',
          message: '只有群主才能设置管理员',
        });
        return;
      }
      // 打开设置管理员对话框
      currentGroupId.value = group.group_id;
      showSetAdminDialog.value = true;
      loadGroupMembersForAdmin();
      break;
    case 'transfer_owner':
      // 检查是否是群主
      const isOwnerForTransfer = await isGroupOwnerSync(group);
      if (!isOwnerForTransfer) {
        $q.notify({
          type: 'warning',
          message: '只有群主才能转让群主',
        });
        return;
      }
      // 打开转让群主对话框
      currentGroupId.value = group.group_id;
      transferOwnerSearchQuery.value = '';
      showTransferOwnerDialog.value = true;
      loadGroupMembersForTransfer();
      break;
    case 'clear_messages':
      $q.dialog({
        title: '确认清空',
        message: `确定要清空群组 "${group.group_name}" 的本地消息吗？此操作只删除本地存储的消息，不会影响服务器上的消息。`,
        cancel: true,
        persistent: true,
      }).onOk(async () => {
        try {
          const { clearGroupChatMessages } = await import('../services/secure-storage');
          const { useChatStore } = await import('../stores/chat');
          const chatStore = useChatStore();
          
          // 调用 Tauri 命令清空群组本地消息
          const deletedCount = await clearGroupChatMessages(group.group_id);
          
          console.log('Tauri 清空群组消息完成，删除数量:', deletedCount);
          
          // 同时更新内存中的消息列表（无论是否正在查看这个群组）
          // 因为消息已经从存储中删除，内存中的也应该同步更新
          try {
            // 从内存中删除该群组的消息
            const memoryDeletedCount = await chatStore.clearUserMessages(group.group_id, []);
            console.log('内存中清空群组消息完成，删除数量:', memoryDeletedCount);
          } catch (error) {
            console.warn('清空内存中的群组消息失败（可能没有在查看该群组）:', error);
          }
          
          // 如果当前正在查看这个群组，需要重新加载消息（因为已清空）
          if (props.currentTargetId === group.group_id) {
            // 触发重新加载消息（通过清空并重新设置目标）
            const { useChatStore } = await import('../stores/chat');
            const chatStore = useChatStore();
            // 清空当前目标，然后重新设置，触发消息重新加载
            chatStore.setTarget('', 'Group');
            // 延迟一下再重新设置，确保清空生效
            setTimeout(() => {
              chatStore.setTarget(group.group_id, 'Group');
            }, 100);
          }
          
          $q.notify({
            type: 'positive',
            message: `已清空群组本地消息，共删除 ${deletedCount} 条消息`,
            timeout: 3000,
          });
        } catch (error: any) {
          console.error('清空群组本地消息失败:', error);
          $q.notify({
            type: 'negative',
            message: error.message || '清空群组本地消息失败',
          });
        }
      });
      break;
    case 'dissolve':
      // 检查是否是群主
      const isOwnerForDissolve = await isGroupOwnerSync(group);
      if (!isOwnerForDissolve) {
        $q.notify({
          type: 'warning',
          message: '只有群主才能解散群组',
        });
        return;
      }
      $q.dialog({
        title: '确认解散',
        message: `确定要解散群组 "${group.group_name}" 吗？此操作不可恢复，所有成员将被移出群组。`,
        cancel: true,
        persistent: true,
      }).onOk(async () => {
        try {
          const { dissolveGroup } = await import('../services/im-group');
          const { useChatStore } = await import('../stores/chat');
          const chatStore = useChatStore();
          
          // 先清理与该群组相关的聊天记录
          try {
            await chatStore.clearUserMessages(group.group_id, []);
            console.log('已清理群组聊天记录:', group.group_id);
          } catch (error) {
            console.warn('清理群组聊天记录失败:', error);
          }
          
          // 调用API解散群组
          await dissolveGroup(group.group_id);
          
          // 如果当前正在查看这个群组，先清空当前目标
          if (props.currentTargetId === group.group_id) {
            emit('select-group', '');
            chatStore.setTarget('', 'Group');
          }
          
          // 强制刷新群组列表（不使用缓存，确保从服务端获取最新数据）
          await loadGroups(true);
          
          $q.notify({
            type: 'positive',
            message: '群组已解散',
          });
        } catch (error: any) {
          console.error('解散群组失败:', error);
          const errorMessage = error.message || '解散群组失败';
          
          // 根据错误类型显示不同的提示
          let caption = '';
          if (errorMessage.includes('无法连接到服务器')) {
            caption = '请检查后端服务器是否正在运行';
          } else if (errorMessage.includes('群主')) {
            caption = '只有群主才能解散群组，请确认您是群主';
          } else {
            caption = '请查看控制台获取更多信息';
          }
          
          $q.notify({
            type: 'negative',
            message: errorMessage,
            caption: caption,
            timeout: 5000,
          });
        }
      });
      break;
    case 'delete':
      // 检查是否是群主
      const isOwnerForDelete = await isGroupOwnerSync(group);
      if (!isOwnerForDelete) {
        $q.notify({
          type: 'warning',
          message: '只有群主才能删除群组',
        });
        return;
      }
      $q.dialog({
        title: '确认删除',
        message: `确定要永久删除群组 "${group.group_name}" 吗？此操作不可恢复，所有数据将被永久删除。`,
        cancel: true,
        persistent: true,
      }).onOk(async () => {
        try {
          const { deleteGroup } = await import('../services/im-group');
          const { useChatStore } = await import('../stores/chat');
          const chatStore = useChatStore();
          
          // 先清理与该群组相关的聊天记录
          try {
            await chatStore.clearUserMessages(group.group_id, []);
            console.log('已清理群组聊天记录:', group.group_id);
          } catch (error) {
            console.warn('清理群组聊天记录失败:', error);
          }
          
          // 调用API删除群组
          await deleteGroup(group.group_id);
          
          // 如果当前正在查看这个群组，先清空当前目标
          if (props.currentTargetId === group.group_id) {
            emit('select-group', '');
            chatStore.setTarget('', 'Group');
          }
          
          // 强制刷新群组列表（不使用缓存，确保从服务端获取最新数据）
          await loadGroups(true);
          
          $q.notify({
            type: 'positive',
            message: '群组已删除',
          });
        } catch (error: any) {
          $q.notify({
            type: 'negative',
            message: error.message || '删除群组失败',
          });
        }
      });
      break;
    case 'leave':
      $q.dialog({
        title: '确认退出',
        message: `确定要退出群组 "${group.group_name}" 吗？`,
        cancel: true,
        persistent: true,
      }).onOk(async () => {
        try {
          const { removeGroupMember } = await import('../services/im-group');
          const { getUserAsync } = await import('../services/auth');
          const { useChatStore } = await import('../stores/chat');
          const chatStore = useChatStore();
          
          const currentUser = await getUserAsync();
          if (!currentUser) {
            throw new Error('未登录，请先登录');
          }
          const currentUserId = currentUser.open_id || (currentUser.snowflake_id ? String(currentUser.snowflake_id) : undefined) || String(currentUser.id);
          
          // 先清理与该群组相关的聊天记录
          try {
            await chatStore.clearUserMessages(group.group_id, []);
            console.log('已清理群组聊天记录:', group.group_id);
          } catch (error) {
            console.warn('清理群组聊天记录失败:', error);
          }
          
          // 调用API退出群组
          await removeGroupMember(group.group_id, currentUserId);
          
          // 如果当前正在查看这个群组，先清空当前目标
          if (props.currentTargetId === group.group_id) {
            emit('select-group', '');
            chatStore.setTarget('', 'Group');
          }
          
          // 强制刷新群组列表（不使用缓存，确保从服务端获取最新数据）
          await loadGroups(true);
          
          $q.notify({
            type: 'positive',
            message: '已退出群组',
          });
        } catch (error: any) {
          $q.notify({
            type: 'negative',
            message: error.message || '退出群组失败',
          });
        }
      });
      break;
  }
};

const handleUpdateGroup = async () => {
  if (!currentGroupId.value) return;
  if (!editGroupName.value.trim()) {
    $q.notify({
      type: 'warning',
      message: '请输入群组名称',
    });
    return;
  }

  updatingGroup.value = true;
  try {
    await updateGroup(currentGroupId.value, {
      group_name: editGroupName.value.trim(),
      introduction: editGroupIntroduction.value.trim() || undefined,
    });
    $q.notify({
      type: 'positive',
      message: '群组信息已更新',
    });
    showEditGroupDialog.value = false;
    // 强制刷新群组列表
    await loadGroups(true);
    // 更新缓存中的群组名称
    const { useChatStore } = await import('../stores/chat');
    const chatStore = useChatStore();
    if (chatStore.currentTargetId === currentGroupId.value) {
      // 如果当前正在查看这个群组，触发名称更新
      emit('select-group', currentGroupId.value, editGroupName.value.trim());
    }
  } catch (error: any) {
    $q.notify({
      type: 'negative',
      message: error.message || '更新群组信息失败',
    });
  } finally {
    updatingGroup.value = false;
  }
};

const handleRemoveMember = async (memberId: string) => {
  if (!currentGroupId.value) return;
  
  removingMember.value = memberId;
  try {
    await removeGroupMember(currentGroupId.value, memberId);
    $q.notify({
      type: 'positive',
      message: '已成功移除成员',
    });
    // 重新加载群成员列表
    await loadGroupMembersForRemove();
    // 强制刷新群组列表以更新成员数量
    await loadGroups(true);
  } catch (error: any) {
    $q.notify({
      type: 'negative',
      message: error.message || '移除成员失败',
    });
  } finally {
    removingMember.value = null;
  }
};

const props = defineProps<{
  currentTargetId?: string | null;
}>();

const emit = defineEmits<{
  (e: 'select-group', groupId: string, groupName?: string): void;
  (e: 'show-details', group: { group_id: string; group_name: string; member_count?: number }): void;
}>();

// 监听添加成员对话框，打开时加载好友列表
watch(showAddMemberDialog, (newVal) => {
  if (newVal) {
    loadFriendsForGroup();
  }
});

// 监听设置管理员对话框，打开时加载群成员列表
watch(showSetAdminDialog, (newVal) => {
  if (newVal) {
    adminSearchQuery.value = '';
    loadGroupMembersForAdmin();
  }
});

// 监听转让群主对话框，打开时加载群成员列表
watch(showTransferOwnerDialog, (newVal) => {
  if (newVal) {
    transferOwnerSearchQuery.value = '';
    loadGroupMembersForTransfer();
  }
});

// 监听移除成员对话框，打开时加载群成员列表
watch(showRemoveMemberDialog, (newVal) => {
  if (newVal) {
    removeMemberSearchQuery.value = '';
    loadGroupMembersForRemove();
  }
});

// 定期刷新定时器
let chatRefreshInterval: number | null = null;

// 监听消息变化，自动更新未读消息数
watch(() => chatStore.messages, () => {
  // 当消息变化时，刷新聊天列表以更新未读消息数
  loadChats().catch(err => {
    console.error('刷新聊天列表失败:', err)
  })
}, { deep: true })

onMounted(async () => {
  // 先加载用户信息，确保 isGroupOwner 能正确判断
  await loadCurrentUser();
  // 然后加载群组列表
  await loadGroups();
  // 定期刷新聊天列表以更新未读消息数（每10秒）
  chatRefreshInterval = window.setInterval(() => {
    loadChats();
  }, 10000);
});

onUnmounted(() => {
  if (chatRefreshInterval !== null) {
    clearInterval(chatRefreshInterval);
  }
});
</script>

<style lang="scss" scoped>
.groups-list {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.groups-header {
  padding: 16px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  gap: 12px;
  background: transparent;
}

.search-input {
  flex: 1;
  
  :deep(.q-field__control) {
    border-radius: 10px;
    border: 1px solid rgba(226, 232, 240, 0.8);
    background: #f8fafc;
    transition: all 0.3s ease;
  }
  
  :deep(.q-field--focused .q-field__control) {
    border-color: #7c3aed;
    background: #FFFFFF;
    box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.12), 0 2px 8px rgba(124, 58, 237, 0.08);
  }
}

.groups-content {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0;
  background: transparent;
}

.group-item {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  gap: 12px;
  cursor: pointer;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  position: relative;
  background: rgba(255, 255, 255, 0.7);
  backdrop-filter: blur(12px);
}

.group-item:hover {
  background: rgba(255, 255, 255, 0.85);
  transform: translateX(2px);
}

.group-item.active {
  background: linear-gradient(90deg, rgba(120, 80, 200, 0.15) 0%, rgba(60, 120, 200, 0.1) 100%);
  border-left: 3px solid #7850C8;
  box-shadow: inset 0 0 20px rgba(120, 80, 200, 0.08);
}

.group-avatar {
  margin-right: 12px;
  flex-shrink: 0;
}

.group-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}

.group-name {
  font-size: 15px;
  font-weight: 500;
  color: #000000;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: 0.1px;
  flex: 1;
  min-width: 0;
}

.group-time {
  font-size: 12px;
  color: #999999;
  margin-left: 8px;
  flex-shrink: 0;
}

.group-preview {
  font-size: 14px;
  color: #666666;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
}

.unread-badge {
  font-size: 11px;
  font-weight: 600;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #FF3B30 0%, #FF2D55 100%);
  box-shadow: 0 2px 6px rgba(255, 59, 48, 0.4), 0 1px 2px rgba(0, 0, 0, 0.1);
  margin-right: 4px;
  color: white;
  animation: badgePulse 2s ease-in-out infinite;
}

.unread-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: linear-gradient(135deg, #FF3B30 0%, #FF2D55 100%);
  margin-right: 4px;
  box-shadow: 0 2px 8px rgba(255, 59, 48, 0.5), 0 0 0 3px rgba(255, 59, 48, 0.15);
  animation: dotPulse 2s ease-in-out infinite;
  position: relative;
}

.unread-dot::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: rgba(255, 59, 48, 0.3);
  animation: dotRipple 2s ease-out infinite;
}

@keyframes badgePulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 2px 6px rgba(255, 59, 48, 0.4), 0 1px 2px rgba(0, 0, 0, 0.1);
  }
  50% {
    transform: scale(1.05);
    box-shadow: 0 3px 8px rgba(255, 59, 48, 0.5), 0 2px 4px rgba(0, 0, 0, 0.15);
  }
}

@keyframes dotPulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 2px 8px rgba(255, 59, 48, 0.5), 0 0 0 3px rgba(255, 59, 48, 0.15);
  }
  50% {
    transform: scale(1.1);
    box-shadow: 0 3px 12px rgba(255, 59, 48, 0.6), 0 0 0 4px rgba(255, 59, 48, 0.2);
  }
}

@keyframes dotRipple {
  0% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.8;
  }
  100% {
    transform: translate(-50%, -50%) scale(2);
    opacity: 0;
  }
}

.empty-state {
  padding: 60px 20px;
  text-align: center;
  color: #666666;
}

.empty-text {
  margin-top: 16px;
  font-size: 14px;
  color: #666666;
}

.groups-content::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.groups-content::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 3px;
}

.groups-content::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  transition: background 0.2s ease;
}

.groups-content::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.3);
}

.friend-select-item {
  display: flex;
  align-items: center;
  padding: 12px;
  gap: 12px;
  cursor: pointer;
  transition: background-color 0.2s;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.friend-select-item:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.friend-select-item:last-child {
  border-bottom: none;
}

.friend-avatar {
  flex-shrink: 0;
}

.friend-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.friend-name {
  font-size: 15px;
  font-weight: 500;
  color: #000000;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: -0.1px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.friend-id {
  font-size: 13px;
  color: #666666;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: -0.05px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.group-menu {
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.menu-list {
  padding: 6px 0;
  background: #FFFFFF;
}

.menu-item {
  padding: 10px 16px;
  min-height: 44px;
  transition: background-color 0.15s ease;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.menu-item:hover {
  background-color: rgba(0, 0, 0, 0.04);
}

.menu-item .q-item__section--avatar {
  padding-right: 12px;
  opacity: 0.7;
}

.menu-item:hover .q-item__section--avatar {
  opacity: 1;
}

.menu-item-label {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.15px;
  line-height: 1.5;
  color: #1f2937;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.menu-item-danger .menu-item-label {
  color: #ef4444;
}

.menu-separator {
  margin: 6px 0;
  background-color: rgba(0, 0, 0, 0.08);
}

.member-select-item {
  display: flex;
  align-items: center;
  padding: 12px;
  gap: 12px;
  cursor: pointer;
  transition: background-color 0.2s;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.member-select-item:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.member-select-item:last-child {
  border-bottom: none;
}

.member-avatar {
  flex-shrink: 0;
}

.member-item {
  display: flex;
  align-items: center;
  padding: 12px;
  gap: 12px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.member-item:last-child {
  border-bottom: none;
}

.avatar-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #C9C9C9;
  color: white;
  font-weight: 500;
  font-size: 16px;
  border-radius: 50%;
  border: 1px solid #E5E5E5;
}

.group-avatar .avatar-placeholder {
  font-size: 18px;
}

.member-info {
  flex: 1;
  min-width: 0;
}

.member-name {
  font-weight: 500;
  margin-bottom: 4px;
  color: #000000;
}

.member-id {
  font-size: 13px;
  color: #666666;
}

/* 对话框样式优化 */
.dialog-card {
  min-width: 400px;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.dialog-header {
  padding: 24px 24px 16px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.dialog-title {
  font-size: 20px;
  font-weight: 600;
  color: #1D1D1F;
  letter-spacing: -0.3px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.dialog-body {
  padding: 20px 24px;
}

.dialog-input {
  font-size: 15px;
  
  :deep(.q-field__label) {
    font-size: 14px;
    font-weight: 500;
    color: #3A3A3C;
    letter-spacing: -0.2px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  
  :deep(.q-field__native) {
    font-size: 15px;
    color: #1D1D1F;
    letter-spacing: -0.1px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  
  :deep(.q-field__input) {
    font-size: 15px;
    color: #1D1D1F;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
}

.dialog-actions {
  padding: 12px 20px 20px 20px;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.dialog-btn {
  font-size: 15px;
  font-weight: 500;
  padding: 8px 16px;
  min-width: 64px;
  letter-spacing: -0.1px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  
  &.dialog-btn-primary {
    font-weight: 600;
  }
}

/* 添加群成员对话框样式 */
.add-member-dialog {
  min-width: 400px;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.add-member-header {
  padding: 24px 24px 16px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.add-member-title {
  font-size: 20px;
  font-weight: 600;
  color: #1D1D1F;
  letter-spacing: -0.3px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.add-member-body {
  padding: 20px 24px;
  max-height: 400px;
  overflow-y: auto;
}

.add-member-search {
  margin-bottom: 16px;
  
  :deep(.q-field__native) {
    font-size: 15px;
    color: #1D1D1F;
    letter-spacing: -0.1px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  
  :deep(.q-field__input) {
    font-size: 15px;
    color: #1D1D1F;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
}

.add-member-actions {
  padding: 12px 20px 20px 20px;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.add-member-btn {
  font-size: 15px;
  font-weight: 500;
  padding: 8px 16px;
  min-width: 64px;
  letter-spacing: -0.1px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* 群组详情样式 */
.group-detail-item {
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.group-detail-item:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.detail-label {
  font-size: 13px;
  color: #666666;
  margin-bottom: 4px;
  font-weight: 500;
}

.detail-value {
  font-size: 15px;
  color: #000000;
  word-break: break-word;
}

/* 群组详情对话框样式 */
.group-details-dialog {
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.group-info-section {
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.members-section {
  margin-top: 24px;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 12px;
}

.section-title {
  display: flex;
  align-items: center;
  font-size: 16px;
  font-weight: 600;
  color: #000000;
  letter-spacing: -0.2px;
}

.member-search-input {
  flex: 1;
  max-width: 250px;
  
  :deep(.q-field__control) {
    border-radius: 8px;
    border: 1px solid rgba(226, 232, 240, 0.8);
    background: #f8fafc;
    transition: all 0.3s ease;
  }
  
  :deep(.q-field--focused .q-field__control) {
    border-color: #7c3aed;
    background: #FFFFFF;
    box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.12);
  }
  
  :deep(.q-field__native) {
    font-size: 14px;
    color: #1D1D1F;
  }
}

.members-list {
  max-height: 400px;
  overflow-y: auto;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 8px;
  background: #fafbfc;
  padding: 8px;
}

.members-list::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.members-list::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 3px;
}

.members-list::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  transition: background 0.2s ease;
}

.members-list::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.3);
}

.empty-members {
  padding: 40px 20px;
  text-align: center;
  color: #666666;
}

.loading-members {
  padding: 40px 20px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.loading-text {
  color: #666666;
  font-size: 14px;
}

.member-item-detail {
  display: flex;
  align-items: center;
  padding: 12px;
  gap: 12px;
  border-radius: 8px;
  transition: background-color 0.2s ease;
  margin-bottom: 4px;
}

.member-item-detail:hover {
  background-color: rgba(255, 255, 255, 0.8);
}

.member-avatar-detail {
  flex-shrink: 0;
}

.member-info-detail {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.member-name-detail {
  font-size: 15px;
  font-weight: 500;
  color: #000000;
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.member-id-detail {
  font-size: 13px;
  color: #666666;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dialog-actions-bottom {
  padding: 16px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.action-btn-danger {
  font-size: 15px;
  font-weight: 500;
  padding: 8px 16px;
  min-width: 120px;
  letter-spacing: -0.1px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.action-btn-danger:hover {
  background-color: rgba(239, 68, 68, 0.1);
}
</style>

